import logging
from typing import Optional, Sequence

from db.init import get_session
from fastapi import APIRouter, Depends, HTTPException, status
from models.common import Pagination
from models.person import (
    Person,
    PersonCreate,
    PersonPublic,
    PersonsPublic,
    PersonUpdate,
)
from sqlmodel import Session, func, select

router = APIRouter(prefix="/persons", tags=["persons"])


@router.post("", response_model=Person)
def create_person(
    person_in: PersonCreate, session: Session = Depends(get_session)
) -> Person:
    """
    创建新的客户
    """
    logging.info(f"person_in: {person_in}")

    person: Person = Person.model_validate(person_in)
    session.add(person)
    session.commit()
    session.refresh(person)
    return person


@router.get("", response_model=PersonsPublic)
def read_persons(
    page: int = 1,
    size: int = 10,
    session: Session = Depends(get_session),
) -> PersonsPublic:
    """
    获取所有客户列表
    """

    total: int = session.exec(select(func.count()).select_from(Person)).one()

    persons: Sequence[Person] = session.exec(
        select(Person).offset((page - 1) * size).limit(size)
    ).all()

    return PersonsPublic(
        items=[PersonPublic.model_validate(p) for p in persons],
        pagination=Pagination(total=total, page=page, size=size),
    )


@router.get("/{person_id}", response_model=Person)
def read_person(person_id: int, session: Session = Depends(get_session)) -> Person:
    """
    根据给定编号获取客户信息。
    """
    person: Optional[Person] = session.get(Person, person_id)

    if not person:
        raise HTTPException(status_code=404, detail="person not found")
    return person


@router.patch("/{person_id}", status_code=status.HTTP_200_OK, response_model=Person)
def update_person(
    person_id: int,
    person_update: PersonUpdate,
    session: Session = Depends(get_session),
) -> Person:
    db_person: Optional[Person] = session.get(Person, person_id)

    if not db_person:
        raise HTTPException(status_code=404, detail="person not found")

    update_data: dict[str, PersonUpdate] = person_update.model_dump(exclude_unset=True)
    db_person.sqlmodel_update(update_data)
    session.commit()
    session.refresh(db_person)
    return db_person


@router.delete("/{person_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_person(person_id: int, session: Session = Depends(get_session)) -> None:
    """
    删除
    """
    logging.info(f"person_id: {person_id}")

    person: Optional[Person] = session.get(Person, person_id)
    if not person:
        raise HTTPException(status_code=404, detail="person not found")
    session.delete(person)
    session.commit()
